#include "usbDataProtocol.h"

UsbDataProtocol::UsbDataProtocol(uint32_t bufSize):ProrocolBase(bufSize)
{

}

UsbDataProtocol::~UsbDataProtocol()
{

}

const uint8_t* UsbDataProtocol::packageBuffer(const uint8_t* buf, uint32_t inlen, int32_t& outlen)
{
	outlen = inlen;
	return buf;
}

int UsbDataProtocol::pushByte(uint8_t point)
{
	uint32_t offset = getRecvOffset();  
    uint8_t* buf = getRxbuf();
    uint32_t bufSize = getBuffSize();
	

	if(offset > bufSize){
		setRecvOffset(0);
	}

	static uint8_t step = 0;
	static uint8_t len = 0;
	static uint8_t data_len = 0;
	static uint16_t xor_sum = 0;

	switch(step)
	{
	    case 0://接收帧头1状态
	        if(point == 0xFF) {
				offset = 0;
	            step++;
	            buf[offset++] = point;
	        }break;
	    case 1://接收帧头2状态
	        if(point == 0xAA) {
	            step++;
	            buf[offset++] = point;
	        } else if(point == 0xFF) {
	            step = 1;
	        } else {
	            step = 0;
	        }
            data_len = 0;
	        break;
	    case 2://接收8字节数据状态
	        buf[offset++] = point;
			data_len++;
	        if(data_len == 8)//利用指针地址偏移判断是否接收完len位数据
	        {
	            step++;
                data_len = 0;
	        }
	        break;
	    case 3://接收异或校验
	        xor_sum = point;
            if(xor_sum == calculate_xor_checksum(&buf[2], 8)){
                buf[offset++] = point;
	            step = 0;
                setRecvOffset(offset);
				return 1;
            } else if(point == 0xFF) {
				offset = 0;
				buf[offset++] = point;
	            step = 1;
	        } else {
	            step = 0;
	        }
	        break;
	    default:step=0;break;//多余状态，正常情况下不可能出现
	}
	setRecvOffset(offset);
	return 0;
}

uint16_t UsbDataProtocol::CRC16_Check(const uint8_t *data,uint8_t len)
{
    uint16_t CRC16 = 0xFFFF;
    uint8_t state,i,j;
    for(i = 0; i < len; i++ )
    {
        CRC16 ^= data[i];
        for( j = 0; j < 8; j++)
        {
            state = CRC16 & 0x01;
            CRC16 >>= 1;
            if(state)
            {
                CRC16 ^= 0xA001;
            }
        }
    }
    return CRC16;
}

uint8_t UsbDataProtocol::calculate_xor_checksum(const uint8_t* data, size_t length) 
{
    uint8_t checksum = 0x00;  // 初始值
    for (size_t i = 0; i < length; ++i) {
        checksum ^= data[i];  // 逐字节异或
    }
    return checksum;
}
